package de.gof.ppstool.xmlimport.ui;

import static de.gof.ppstool.util.LogUtil.begin;
import static de.gof.ppstool.util.LogUtil.end;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import de.gof.ppstool.bestellverwaltung.IBestellverwaltung;
import de.gof.ppstool.bestellverwaltung.db.BestellpositionEntity;
import de.gof.ppstool.bestellverwaltung.db.Bestellung;
import de.gof.ppstool.fertigungsverwaltung.IFertigungsverwaltung;
import de.gof.ppstool.fertigungsverwaltung.db.Fehlendeteile;
import de.gof.ppstool.fertigungsverwaltung.db.FehlendeteileNotFoundException;
import de.gof.ppstool.fertigungsverwaltung.db.Fertigungsauftrag;
import de.gof.ppstool.fertigungsverwaltung.db.FertigungsauftragNotFoundException;
import de.gof.ppstool.fertigungsverwaltung.db.Fertigungsauftragsposition;
import de.gof.ppstool.fertigungsverwaltung.db.FertigungsauftragspositionDuplikatException;
import de.gof.ppstool.lagerverwaltung.ILagerverwaltung;
import de.gof.ppstool.lagerverwaltung.db.Arbeitsplatz;
import de.gof.ppstool.lagerverwaltung.db.ArbeitsplatzNotFoundException;
import de.gof.ppstool.lagerverwaltung.db.Teil;
import de.gof.ppstool.lagerverwaltung.db.TeilNotFoundException;
import de.gof.ppstool.staticdata.IStaticDataVerwaltung;
import de.gof.ppstool.staticdata.StaticDataNotFoundException;
import de.gof.ppstool.staticdata.db.StaticData;
import de.gof.ppstool.util.XMLException;

/**
 * XMLImporter
 */
@ManagedBean(name = XMLImporterBean.NAME)
@SessionScoped
public class XMLImporterBean implements Serializable {
	private static final long serialVersionUID = 3862426497936999660L;
	//private static String filename = "C:\\tmp\\periode2_results_original_mod.xml";
	//private static String filename = "..\\PPSTEST\\testdata\\resultlist.xml";
	//private static String filename = "..\\PPSTEST\\testdata\\periode4_results.xml";
	private static String filename = "..\\PPSTEST\\testdata\\Results_Periode6.xml";
	private File file;
	public static final String NAME = "xb";
	private static final Log LOG = LogFactory.getLog(XMLImporterBean.class);
	private static final boolean DEBUG = LOG.isDebugEnabled();
	private static final boolean TRACE = LOG.isTraceEnabled();
	@ManagedProperty(value = "#{" + IBestellverwaltung.NAME + "}")
	private IBestellverwaltung bv;
	@ManagedProperty(value = "#{" + ILagerverwaltung.NAME + "}")
	private ILagerverwaltung lv;
	@ManagedProperty(value = "#{" + IFertigungsverwaltung.NAME + "}")
	private IFertigungsverwaltung fv;
	@ManagedProperty(value = "#{" + IStaticDataVerwaltung.NAME + "}")
	private IStaticDataVerwaltung sdv;
	@ManagedProperty(value = "#{" + XMLImporterBean.NAME + "}")
	private XMLImporterBean xb;

	public XMLImporterBean() {
		super();
	}

	public XMLImporterBean getXMLImporterBean() {
		return xb;
	}

	public void setXMLImporterBean(XMLImporterBean xb) {
		this.xb = xb;
	}

	/**
	 * Liest die per Parameter uebergebene Datei ein
	 * @param uri  Pfad+Dateiname zur XML Datei (e.g. "C:\\tmp\\datei.xml")
	 * @throws XMLException
	 */
	public void readXML(String uri) throws XMLException {
		if (uri.equals(""))
			throw new XMLException("URI is null!");

		filename = uri;
		readXML();
	}

	/**
	 * Liest die uebergebene Datei ein
	 * @param inputfile  Inputfile
	 * @throws XMLException
	 */
	public void readXML(File inputfile) throws XMLException {
		if (inputfile == null)
			throw new XMLException("File is null!");

		file = inputfile;
		readXML();
	}

	/**
	 * Reads the results XML file
	 * @throws XMLException
	 */
	public void readXML() throws XMLException {
		if (DEBUG)
			begin(LOG);

		try {
			//Read file...
			if (file == null)
				file = new File(filename);

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			dbf.setNamespaceAware(true);
			dbf.setValidating(false);
			DocumentBuilder db = dbf.newDocumentBuilder();
			//remove blank lines if any
			file = cleanupFile(file);
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			//Checking if the file is an input file...
			if (doc.getDocumentElement().getNodeName().toString() != "results") {
				throw new XMLException("Invalid inputfile: " + filename);
			}

			//Parsing
			parseWarehousestock(doc);
			//Working
			//parseInwardstockmovement(doc);  	//not needed at the moment
			parseFutureinwardstockmovement(doc);
			//Working
			parseIdletimecosts(doc);
			//Working (maybe more data fields needed...)
			parseWaitinglistworkstations(doc);
			parseWaitingliststock(doc);
			parseOrdersinwork(doc);
			//parseCompletedorders(doc); 			//not needed at the moment
			//parseCycletimes(doc); 				//not needed at the moment
			parseResult(doc);
		} catch (Exception e) {
			e.printStackTrace();
			throw new XMLException("Bugs are invading the XML Parser!!");
		}

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Removes blank lines from the file
	 * @param input
	 * @return
	 */
	private static File cleanupFile(File input) {
		try {
			File tempFile = File.createTempFile("xmlimport", ".tmp");
			tempFile.deleteOnExit();
			BufferedReader br = new BufferedReader(new FileReader(input));
			PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
			String line = null;
			while ((line = br.readLine()) != null) {
				if (!line.trim().equals("\n") && !line.trim().equals("")) {
					pw.println(line);
					pw.flush();
				}

			}
			pw.close();
			br.close();
			return tempFile;
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}

		return null;
	}

	/**
	 * Parses the <warehousestock> section
	 * @param docpar
	 * @throws XMLException
	 */
	private void parseWarehousestock(Document docpar) throws XMLException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <warehousestock>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("warehousestock");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node warehousetmp = nodeLst.item(0);
		NodeList articletmplst = warehousetmp.getChildNodes();
		for (int x = 0; x < articletmplst.getLength(); x++) {
			Node articletmp = articletmplst.item(x);
			if (articletmp.getNodeType() == Node.ELEMENT_NODE) {
				if ((!articletmp.getParentNode().getNodeName()
						.equals("warehousestock") == true)
						|| (!articletmp.getNodeName().equals("article") == true))
					continue;

				counter++;
				NamedNodeMap attributemap = articletmp.getAttributes();
				int id = -1;
				int amount = -1;
				int startamount = -1;
				double pct = -1;
				double price = -1;
				double stockvalue = -1;
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "id")
						id = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "amount")
						amount = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "startamount")
						startamount = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "pct") {
						if (attrtmp.getNodeValue().contains("."))
							pct = Double.valueOf(attrtmp.getNodeValue());
						else
							pct = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "price") {
						if (attrtmp.getNodeValue().contains("."))
							price = Double.valueOf(attrtmp.getNodeValue());
						else
							price = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "stockvalue") {
						if (attrtmp.getNodeValue().contains("."))
							stockvalue = Double.valueOf(attrtmp.getNodeValue());
						else
							stockvalue = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

				}
				//DB insert
				createWarehousestockInserts(id, amount, startamount, pct,
						price, stockvalue);
			}

		}
		if (DEBUG)
			LOG.debug("Warehousestock counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <inwardstockmovement> section
	 * @param docpar
	 * @throws XMLException
	 */
	@SuppressWarnings("unused")
	private void parseInwardstockmovement(Document docpar) throws XMLException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <inwardstockmovement>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("inwardstockmovement");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node inwardstockmovementtmp = nodeLst.item(0);
		NodeList ordertmplst = inwardstockmovementtmp.getChildNodes();
		for (int x = 0; x < ordertmplst.getLength(); x++) {
			Node ordertmp = ordertmplst.item(x);
			if (ordertmp.getNodeType() == Node.ELEMENT_NODE) {
				if ((!ordertmp.getParentNode().getNodeName()
						.equals("inwardstockmovement") == true)
						|| (!ordertmp.getNodeName().equals("order") == true))
					continue;

				counter++;
				NamedNodeMap attributemap = ordertmp.getAttributes();
				int orderperiod = -1;
				int mode = -1;
				int article = -1;
				int amount = -1;
				int time = -1;
				double materialcosts = -1;
				double ordercosts = -1;
				double entirecosts = -1;
				double piececosts = -1;
				// Still room for small performance optimizations -> add continue's
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "orderperiod")
						orderperiod = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "mode")
						mode = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "article")
						article = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "amount")
						amount = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "time")
						time = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "materialcosts") {
						if (attrtmp.getNodeValue().contains("."))
							materialcosts = Double.valueOf(attrtmp
									.getNodeValue());
						else
							materialcosts = Double.valueOf(attrtmp
									.getNodeValue().replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "ordercosts") {
						if (attrtmp.getNodeValue().contains("."))
							ordercosts = Double.valueOf(attrtmp.getNodeValue());
						else
							ordercosts = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "entirecosts") {
						if (attrtmp.getNodeValue().contains("."))
							entirecosts = Double
									.valueOf(attrtmp.getNodeValue());
						else
							entirecosts = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "piececosts") {
						if (attrtmp.getNodeValue().contains("."))
							piececosts = Double.valueOf(attrtmp.getNodeValue());
						else
							piececosts = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

				}
				createInwardstockmovementInserts(orderperiod, mode, article,
						amount, time, materialcosts, ordercosts, entirecosts,
						piececosts);
			}

		}
		if (DEBUG)
			LOG.debug("Inwardstockmovement counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <futureinwardstockmovement> section
	 * @param docpar
	 * @throws XMLException
	 */
	private void parseFutureinwardstockmovement(Document docpar)
			throws XMLException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <futureinwardstockmovement>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc
				.getElementsByTagName("futureinwardstockmovement");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		for (int x = 0; x < tmpnodelst.getLength(); x++) {
			Node nodeitem = tmpnodelst.item(x);
			if (nodeitem.getNodeType() == Node.ELEMENT_NODE) {
				if ((!nodeitem.getParentNode().getNodeName()
						.equals("futureinwardstockmovement") == true)
						|| (!nodeitem.getNodeName().equals("order") == true))
					continue;

				counter++;
				NamedNodeMap attributemap = nodeitem.getAttributes();
				int orderperiod = -1;
				int id = -1;
				int mode = -1;
				int article = -1;
				int amount = -1;
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "orderperiod")
						orderperiod = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "id")
						id = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "mode")
						mode = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "article")
						article = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "amount")
						amount = Integer.parseInt(attrtmp.getNodeValue());

				}
				createFutureinwardstockmovementInserts(orderperiod, id, mode,
						article, amount);
			}

		}
		if (DEBUG)
			LOG.debug("Futureinwardstockmovement counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <idletimecosts> section
	 * @param docpar
	 * @throws XMLException  
	 */
	private void parseIdletimecosts(Document docpar) throws XMLException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <idletimecosts>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("idletimecosts");
		// if (nodeLst.getLength() > 1)
		// System.out.println("something is wrong! "+nodeLst.toString() +"- should only be 1 Node!");
		// Ignored, second Node is <sum> -> not needed, can be calculated from database data
		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		for (int x = 0; x < tmpnodelst.getLength(); x++) {
			Node nodeitem = tmpnodelst.item(x);
			if (nodeitem.getNodeType() == Node.ELEMENT_NODE) {
				if ((!nodeitem.getParentNode().getNodeName()
						.equals("idletimecosts") == true)
						|| (!nodeitem.getNodeName().equals("workplace") == true))
					continue;

				counter++;
				NamedNodeMap attributemap = nodeitem.getAttributes();
				int id = -1;
				int setupevents = -1;
				int idletime = -1;
				double wageidletimecosts = -1;
				double wagecosts = -1;
				double machineidletimecosts = -1;
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "id")
						//workplaceId
						id = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "setupevents")
						setupevents = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "idletime")
						idletime = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "wageidletimecosts") {
						if (attrtmp.getNodeValue().contains("."))
							wageidletimecosts = Double.valueOf(attrtmp
									.getNodeValue());
						else
							wageidletimecosts = Double.valueOf(attrtmp
									.getNodeValue().replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "wagecosts") {
						if (attrtmp.getNodeValue().contains("."))
							wagecosts = Double.valueOf(attrtmp.getNodeValue());
						else
							wagecosts = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "machineidletimecosts") {
						if (attrtmp.getNodeValue().contains("."))
							machineidletimecosts = Double.valueOf(attrtmp
									.getNodeValue());
						else
							machineidletimecosts = Double.valueOf(attrtmp
									.getNodeValue().replace(',', '.'));

					}

				}
				createIdletimecostsInserts(id, setupevents, idletime,
						wageidletimecosts, wagecosts, machineidletimecosts);
			}

		}
		if (DEBUG)
			LOG.debug("Idletimecosts counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <waitinglistworkstations> section
	 * @param docpar
	 * @throws XMLException
	 * @throws ArbeitsplatzNotFoundException  
	 * @throws FertigungsauftragNotFoundException  
	 * @throws FertigungsauftragspositionDuplikatException  
	 * @throws TeilNotFoundException  
	 */
	private void parseWaitinglistworkstations(Document docpar)
			throws XMLException, TeilNotFoundException,
			FertigungsauftragspositionDuplikatException,
			FertigungsauftragNotFoundException, ArbeitsplatzNotFoundException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <waitinglistworkstations>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("waitinglistworkstations");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		for (int x = 0; x < tmpnodelst.getLength(); x++) {
			Node nodeitem = tmpnodelst.item(x);
			if (nodeitem.getNodeType() == Node.ELEMENT_NODE) {
				if ((!nodeitem.getParentNode().getNodeName()
						.equals("waitinglistworkstations") == true)
						|| (!nodeitem.getNodeName().equals("workplace") == true))
					continue;

				counter++;
				int workplaceId = -1;
				int workplaceTimeneed = -1;
				NamedNodeMap attributemap = nodeitem.getAttributes();
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "id")
						workplaceId = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "timeneed")
						workplaceTimeneed = Integer.parseInt(attrtmp
								.getNodeValue());

				}
				//variables for waitinglist
				int period = -1;
				int order = -1;
				int firstbatch = -1;
				int lastbatch = -1;
				int item = -1;
				int amount = -1;
				int waitinglistTimeneed = -1;
				//If waitinglist is available...
				if (nodeitem.hasChildNodes()) {
					NodeList waitingListNodes = nodeitem.getChildNodes();
					for (int z = 0; z < waitingListNodes.getLength(); z++) {
						Node waitinglistItem = waitingListNodes.item(z);
						if (waitinglistItem.getNodeType() == Node.ELEMENT_NODE) {
							NamedNodeMap waitinglistItemMap = waitinglistItem
									.getAttributes();
							for (int s = 0; s < waitinglistItemMap.getLength(); s++) {
								Node eattrtmp = waitinglistItemMap.item(s);
								if (eattrtmp.getLocalName() == "period")
									period = Integer.parseInt(eattrtmp
											.getNodeValue());

								if (eattrtmp.getLocalName() == "order")
									order = Integer.parseInt(eattrtmp
											.getNodeValue());

								if (eattrtmp.getLocalName() == "firstbatch")
									firstbatch = Integer.parseInt(eattrtmp
											.getNodeValue());

								if (eattrtmp.getLocalName() == "lastbatch")
									lastbatch = Integer.parseInt(eattrtmp
											.getNodeValue());

								if (eattrtmp.getLocalName() == "item")
									item = Integer.parseInt(eattrtmp
											.getNodeValue());

								if (eattrtmp.getLocalName() == "amount")
									amount = Integer.parseInt(eattrtmp
											.getNodeValue());

								if (eattrtmp.getLocalName() == "timeneed")
									waitinglistTimeneed = Integer
											.parseInt(eattrtmp.getNodeValue());

							}
							//DB insert (inner level)
							createWaitinglistworksatationsInserts(workplaceId,
									workplaceTimeneed, period, order,
									firstbatch, lastbatch, item, amount,
									waitinglistTimeneed);
						}

					}
				}

				//DB insert
				createWaitinglistworksatationsInserts(workplaceId,
						workplaceTimeneed);
			}

		}
		if (DEBUG)
			LOG.debug("Waitinglistworkstations counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <waitingliststock> section
	 * @param docpar
	 * @throws XMLException
	 * @throws FehlendeteileNotFoundException  
	 * @throws FertigungsauftragNotFoundException  
	 * @throws FertigungsauftragspositionDuplikatException  
	 * @throws TeilNotFoundException  
	 */
	private void parseWaitingliststock(Document docpar) throws XMLException,
			FehlendeteileNotFoundException, TeilNotFoundException,
			FertigungsauftragspositionDuplikatException,
			FertigungsauftragNotFoundException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <waitingliststock>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("waitingliststock");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		for (int x = 0; x < tmpnodelst.getLength(); x++) {
			Node nodeitem = tmpnodelst.item(x);
			int id = -1;
			NamedNodeMap tlattributemap = nodeitem.getAttributes();
			try {
				if ((nodeitem.getParentNode().getNodeName()
						.equals("waitingliststock") == false)
						|| (nodeitem.getNodeName().equals("missingpart") == false))
					continue;

				if ((nodeitem.getNodeType() == Node.ELEMENT_NODE)
						&& (tlattributemap.item(0).getLocalName() == "id"))
					id = Integer
							.parseInt(tlattributemap.item(0).getNodeValue());

			} catch (Exception e) {
				throw new XMLException(
						"Error parsing TL Element of <waitingliststock>");
			}

			if (nodeitem.hasChildNodes()) {
				NodeList waitingListNodes = nodeitem.getChildNodes();
				for (int z = 0; z < waitingListNodes.getLength(); z++) {
					Node waitinglistItem = waitingListNodes.item(z);
					if (waitinglistItem.getNodeType() == Node.ELEMENT_NODE) {
						if ((!waitinglistItem.getParentNode().getNodeName()
								.equals("missingpart") == true)
								|| (!waitinglistItem.getNodeName().equals(
										"waitinglist") == true))
							continue;

						counter++;
						int period = -1;
						int order = -1;
						int firstbatch = -1;
						int lastbatch = -1;
						int item = -1;
						int amount = -1;
						NamedNodeMap attributemap = waitinglistItem
								.getAttributes();
						for (int y = 0; y < attributemap.getLength(); y++) {
							Node attrtmp = attributemap.item(y);
							if (attrtmp.getLocalName() == "period")
								period = Integer.parseInt(attrtmp
										.getNodeValue());

							if (attrtmp.getLocalName() == "order")
								order = Integer
										.parseInt(attrtmp.getNodeValue());

							if (attrtmp.getLocalName() == "firstbatch")
								firstbatch = Integer.parseInt(attrtmp
										.getNodeValue());

							if (attrtmp.getLocalName() == "lastbatch")
								lastbatch = Integer.parseInt(attrtmp
										.getNodeValue());

							if (attrtmp.getLocalName() == "item")
								item = Integer.parseInt(attrtmp.getNodeValue());

							if (attrtmp.getLocalName() == "amount")
								amount = Integer.parseInt(attrtmp
										.getNodeValue());

						}
						//DB insert (lower level)
						createWaitingliststockInserts(id, period, order,
								firstbatch, lastbatch, item, amount);
					}

				}
			}

		}
		if (DEBUG)
			LOG.debug("Waitingliststock counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <ordersinwork> section
	 * @param docpar
	 * @throws XMLException
	 * @throws ArbeitsplatzNotFoundException  
	 * @throws FertigungsauftragNotFoundException  
	 * @throws FertigungsauftragspositionDuplikatException  
	 * @throws TeilNotFoundException  
	 */
	private void parseOrdersinwork(Document docpar) throws XMLException,
			TeilNotFoundException, FertigungsauftragspositionDuplikatException,
			FertigungsauftragNotFoundException, ArbeitsplatzNotFoundException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <ordersinwork>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("ordersinwork");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		for (int x = 0; x < tmpnodelst.getLength(); x++) {
			Node nodeitem = tmpnodelst.item(x);
			if (nodeitem.getNodeType() == Node.ELEMENT_NODE) {
				if ((!nodeitem.getParentNode().getNodeName()
						.equals("ordersinwork") == true)
						|| (!nodeitem.getNodeName().equals("workplace") == true))
					continue;

				counter++;
				int id = -1;
				int period = -1;
				int order = -1;
				int batch = -1;
				int item = -1;
				int amount = -1;
				int timeNeed = -1;
				NamedNodeMap attributemap = nodeitem.getAttributes();
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "id")
						id = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "period")
						period = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "order")
						order = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "batch")
						batch = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "item")
						item = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "amount")
						amount = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "timeneed")
						timeNeed = Integer.parseInt(attrtmp.getNodeValue());

				}
				//DB inserts
				createOrdersinworkInserts(id, period, order, batch, item,
						amount, timeNeed);
			}

		}
		if (DEBUG)
			LOG.debug("Ordersinwork counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <completedorders> section
	 * @param docpar
	 * @throws XMLException
	 */
	@SuppressWarnings("unused")
	private void parseCompletedorders(Document docpar) throws XMLException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <completedorders>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("completedorders");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		for (int x = 0; x < tmpnodelst.getLength(); x++) {
			Node nodeitem = tmpnodelst.item(x);
			int period = -1;
			int id = -1;
			int item = -1;
			int quantity = -1;
			double cost = -1;
			double averageunitcosts = -1;
			if (nodeitem.getNodeType() == Node.ELEMENT_NODE) {
				if ((!nodeitem.getParentNode().getNodeName()
						.equals("completedorders") == true)
						|| (!nodeitem.getNodeName().equals("order") == true))
					continue;

				counter++;
				NamedNodeMap attributemap = nodeitem.getAttributes();
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "period")
						period = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "id")
						id = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "item")
						item = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "quantity")
						quantity = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "cost") {
						if (attrtmp.getNodeValue().contains("."))
							cost = Double.valueOf(attrtmp.getNodeValue());
						else
							cost = Double.valueOf(attrtmp.getNodeValue()
									.replace(',', '.'));

					}

					if (attrtmp.getLocalName() == "averageunitcosts") {
						if (attrtmp.getNodeValue().contains("."))
							averageunitcosts = Double.valueOf(attrtmp
									.getNodeValue());
						else
							averageunitcosts = Double.valueOf(attrtmp
									.getNodeValue().replace(',', '.'));

					}

				}
				//DB inserts (tl)
				createCompletedordersInserts(period, id, item, quantity, cost,
						averageunitcosts);
			}

			NodeList batchnodelst = nodeitem.getChildNodes();
			//lower level
			for (int z = 0; z < batchnodelst.getLength(); z++) {
				Node batchNode = batchnodelst.item(z);
				if (batchNode.getNodeType() == Node.ELEMENT_NODE) {
					if ((batchNode.getParentNode().getNodeName()
							.equals("order") == false)
							|| (batchNode.getNodeName().equals("batch") == false))
						continue;

					int llid = -1;
					int amount = -1;
					int cycletime = -1;
					double llcost = -1;
					NamedNodeMap attributemap = batchNode.getAttributes();
					for (int y = 0; y < attributemap.getLength(); y++) {
						Node attrtmp = attributemap.item(y);
						if (attrtmp.getLocalName() == "id")
							llid = Integer.parseInt(attrtmp.getNodeValue());

						if (attrtmp.getLocalName() == "amount")
							amount = Integer.parseInt(attrtmp.getNodeValue());

						if (attrtmp.getLocalName() == "cycletime")
							cycletime = Integer
									.parseInt(attrtmp.getNodeValue());

						if (attrtmp.getLocalName() == "cost") {
							if (attrtmp.getNodeValue().contains("."))
								llcost = Double.valueOf(attrtmp.getNodeValue());
							else
								llcost = Double.valueOf(attrtmp.getNodeValue()
										.replace(',', '.'));

						}

					}
					//DB insert
					createCompletedordersInserts(llid, amount, cycletime,
							llcost);
				}

			}
		}
		if (DEBUG)
			LOG.debug("Completedorders counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <cycletimes> section
	 * @param docpar
	 * @throws XMLException
	 */
	@SuppressWarnings("unused")
	private void parseCycletimes(Document docpar) throws XMLException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <cycletimes>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("cycletimes");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		//top level attributes
		int startedorders = -1;
		int waitingorders = -1;
		NamedNodeMap tlattributemap = node.getAttributes();
		for (int y = 0; y < tlattributemap.getLength(); y++) {
			Node attrtmp = tlattributemap.item(y);
			if (attrtmp.getLocalName() == "startedorders")
				startedorders = Integer.parseInt(attrtmp.getNodeValue());

			if (attrtmp.getLocalName() == "waitingorders")
				waitingorders = Integer.parseInt(attrtmp.getNodeValue());

		}
		//DB inserts top level
		createCycletimesInserts(startedorders, waitingorders);
		for (int x = 0; x < tmpnodelst.getLength(); x++) {
			Node nodeitem = tmpnodelst.item(x);
			if (nodeitem.getNodeType() == Node.ELEMENT_NODE) {
				if ((!nodeitem.getParentNode().getNodeName()
						.equals("cycletimes") == true)
						|| (!nodeitem.getNodeName().equals("order") == true))
					continue;

				counter++;
				int period = -1;
				String starttime = null;
				String finishtime = null;
				int cycletimemin = -1;
				double cycletimefactor = -1;
				NamedNodeMap attributemap = nodeitem.getAttributes();
				for (int y = 0; y < attributemap.getLength(); y++) {
					Node attrtmp = attributemap.item(y);
					if (attrtmp.getLocalName() == "period")
						period = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "starttime")
						starttime = attrtmp.getNodeValue();

					if (attrtmp.getLocalName() == "finishtime")
						finishtime = attrtmp.getNodeValue();

					if (attrtmp.getLocalName() == "cycletimemin")
						cycletimemin = Integer.parseInt(attrtmp.getNodeValue());

					if (attrtmp.getLocalName() == "cycletimefactor") {
						if (attrtmp.getNodeValue().contains("."))
							cycletimefactor = Double.valueOf(attrtmp
									.getNodeValue());
						else
							cycletimefactor = Double.valueOf(attrtmp
									.getNodeValue().replace(',', '.'));

					}

				}
				// DB inserts
				createCycletimesInserts(period, starttime, finishtime,
						cycletimemin, cycletimefactor);
			}

		}
		if (DEBUG)
			LOG.debug("Cycletimes counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * Parses the <result> section
	 * Not needed at the moment
	 * @param docpar
	 * @throws XMLException  
	 * @throws StaticDataNotFoundException  
	 * @throws NumberFormatException  
	 */
	@SuppressWarnings("unused")
	private void parseResult(Document docpar) throws XMLException,
			NumberFormatException, StaticDataNotFoundException {
		if (DEBUG)
			begin(LOG);

		if (DEBUG)
			LOG.debug("Parsing <result>...");

		Document doc = docpar;
		int counter = 0;
		NodeList nodeLst = doc.getElementsByTagName("results");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		//...do the magic here...
		Node node = nodeLst.item(0);
		NodeList tmpnodelst = node.getChildNodes();
		//top level attributes
		String xmlperiod = "-1";
		NamedNodeMap tlattributemap = node.getAttributes();
		for (int y = 0; y < tlattributemap.getLength(); y++) {
			Node attrtmp = tlattributemap.item(y);
			if (attrtmp.getLocalName() == "period")
				xmlperiod = attrtmp.getNodeValue();

		}
		//StorageCosts
		nodeLst = doc.getElementsByTagName("storagecosts");
		if (nodeLst.getLength() > 1)
			throw new XMLException(
					"More than 1 Node found - some results may be lost "
							+ "(while parsing: <"
							+ nodeLst.item(0).getParentNode().toString() + ">)");

		node = nodeLst.item(0);
		tmpnodelst = node.getChildNodes();
		//attributes
		String storagecosts = "-1";
		tlattributemap = node.getAttributes();
		for (int y = 0; y < tlattributemap.getLength(); y++) {
			Node attrtmp = tlattributemap.item(y);
			if (attrtmp.getLocalName() == "current")
				storagecosts = attrtmp.getNodeValue();

		}
		createResultInserts(xmlperiod, storagecosts);
		if (DEBUG)
			LOG.debug("result counter: " + counter);

		if (DEBUG)
			end(LOG);

	}

	/* ******************************************************************************************************************************************** *
	 * DB inserts															                                                                        *
	 * ******************************************************************************************************************************************** */
	/**
	 * Adds the current <warehousestock> element into the database
	 * @param id
	 * @param amount
	 * @param startamount
	 * @param pct
	 * @param price
	 * @param stockvalue
	 */
	private void createWarehousestockInserts(int id, int amount,
			int startamount, double pct, double price, double stockvalue) {
		if (TRACE)
			LOG.trace("DB insert: " + id + "; " + amount + "; " + startamount
					+ "; " + pct + "; " + price + "; " + stockvalue);

		try {
			//search
			Teil x = lv.findeTeilNachTeilId(Long.valueOf(id));
			if (x != null) {
				x.setLagerbestand(amount);
				x.setPreis((price));
				x = lv.aendereTeil(x);
			} else {
				throw new XMLException("Part (" + id
						+ ") not found -> this shouldn't happen!");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * Adds the current <inwardstockmovement> element into the database
	 * Not in use at the moment
	 * @param orderperiod
	 * @param mode
	 * @param article
	 * @param amount
	 * @param time
	 * @param materialcosts
	 * @param ordercosts
	 * @param entirecosts
	 * @param piececosts
	 */
	private void createInwardstockmovementInserts(int orderperiod, int mode,
			int article, int amount, int time, double materialcosts,
			double ordercosts, double entirecosts, double piececosts) {
		if (TRACE)
			LOG.trace("DB insert: " + orderperiod + "; " + mode + "; "
					+ article + "; " + amount + "; " + time + "; "
					+ materialcosts + "; " + ordercosts + "; " + entirecosts
					+ "; " + piececosts);

		//Data not needed at this stage
	}

	/**
	 * Adds the current <futureinwardstockmovement> element into the database
	 * @param orderperiod
	 * @param id
	 * @param mode
	 * @param article
	 * @param amount
	 */
	private void createFutureinwardstockmovementInserts(int orderperiod,
			int id, int mode, Integer article, int amount) {
		if (TRACE)
			LOG.trace("DB insert: " + orderperiod + "; " + id + "; " + mode
					+ "; " + article + "; " + amount);

		try {
			//search
			Teil x = lv.findeTeilNachTeilId(Long.valueOf(article));
			if (x != null) {
				x.setBestelltemenge(amount);
				x = lv.aendereTeil(x);
			} else {
				throw new XMLException("Part (" + article
						+ ") not found -> this shouldn't happen!");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			Teil teil = lv.findeTeilNachTeilId(Long.valueOf(article));
			//create new order
			Bestellung b = new Bestellung();
			b.setBestelltag(String.valueOf(orderperiod));
			b = bv.erstelleBestellung(b);
			//create new orderposition
			BestellpositionEntity bp = new BestellpositionEntity();
			bp.setBestellart(String.valueOf(mode));
			bp.setBestellmenge(amount);
			bp.setBestellung(b);
			bp.setBestelldauer(teil.getWiederbeschaffungszeit());
			bp.setBestellkosten(teil.getBestellkosten());
			bp.setTeil(teil);
			bp.setTeilId(article.toString());
			bp = bv.erstelleBestellposition(bp);
			List<BestellpositionEntity> bpl = new ArrayList<BestellpositionEntity>();
			bpl.add(bp);
			b.setBestellpositionen(bpl);
			b = bv.aendereBestellung(b);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * Adds the current <idletimecosts> element into the database
	 * @param id
	 * @param setupevents
	 * @param idletime
	 * @param wageidletimecosts
	 * @param wagecosts
	 * @param machineidletimecosts
	 * @throws XMLException  
	 * @throws ArbeitsplatzNotFoundException  
	 */
	private void createIdletimecostsInserts(int id, int setupevents,
			int idletime, double wageidletimecosts, double wagecosts,
			double machineidletimecosts) throws XMLException {
		if (TRACE)
			LOG.trace("DB insert: " + id + "; " + setupevents + "; " + idletime
					+ "; " + wageidletimecosts + "; " + wagecosts + "; "
					+ machineidletimecosts);

		//TODO pruefen ob die reine leerlaufzeit ausreicht, oder ob man die DB erweitern muss um weitere Spalten  
		Arbeitsplatz arbeitsplatz;
		try {
			arbeitsplatz = lv.findeArbeitsplatzNachId(Long.valueOf(id));
		} catch (ArbeitsplatzNotFoundException e) {
			throw new XMLException("Arbeitsplatz: " + id
					+ " not found -> this shouldn't happen!");
		}

		arbeitsplatz.setLeerlaufzeit(String.valueOf(idletime));
		try {
			lv.aendereArbeitsplatz(arbeitsplatz);
		} catch (ArbeitsplatzNotFoundException e) {
			throw new XMLException(
					"Error while updating a workstation in createIdletimecostsInserts()");
		}

	}

	/**
	 * Adds the current <waitinglistworkstations> element into the database (inner level)
	 * @param workplaceId
	 * @param workplaceTimeneed
	 * @param period
	 * @param order
	 * @param firstbatch
	 * @param lastbatch
	 * @param item
	 * @param amount
	 * @param waitinglistTimeneed
	 * @throws XMLException  
	 * @throws TeilNotFoundException  
	 * @throws FertigungsauftragNotFoundException  
	 * @throws FertigungsauftragspositionDuplikatException  
	 * @throws ArbeitsplatzNotFoundException  
	 */
	private void createWaitinglistworksatationsInserts(int workplaceId,
			int workplaceTimeneed, int period, int order, int firstbatch,
			int lastbatch, int item, int amount, int waitinglistTimeneed)
			throws XMLException, TeilNotFoundException,
			FertigungsauftragspositionDuplikatException,
			FertigungsauftragNotFoundException, ArbeitsplatzNotFoundException {
		if (TRACE)
			LOG.trace("DB insert (waitinglist): (" + workplaceId + "; "
					+ workplaceTimeneed + "); " + period + "; " + order + "; "
					+ firstbatch + "; " + lastbatch + "; " + item + "; "
					+ amount + "; " + waitinglistTimeneed);

		Arbeitsplatz arbeitsplatz;
		try {
			arbeitsplatz = lv
					.findeArbeitsplatzNachId(Long.valueOf(workplaceId));
		} catch (ArbeitsplatzNotFoundException e) {
			throw new XMLException("Arbeitsplatz: " + workplaceId
					+ " not found -> this shouldn't happen!");
		}

		arbeitsplatz.setZeitbedarfVorperiode(String.valueOf(workplaceTimeneed));
		List<Fertigungsauftrag> warteschlangenAuftrage = new ArrayList<Fertigungsauftrag>();
		warteschlangenAuftrage = arbeitsplatz.getWarteschlangenAuftrage();
		List<Fertigungsauftragsposition> fapl = new ArrayList<Fertigungsauftragsposition>();
		Fertigungsauftragsposition fap = new Fertigungsauftragsposition();
		Fertigungsauftrag fa = new Fertigungsauftrag();
		fa.setBemerkung("Waitinglistworkstation " + workplaceId);
		fa.setInterneAuftragsId(String.valueOf(order));
		fa.setZeitbedarf(String.valueOf(waitinglistTimeneed));
		fa.setTagdesauftrags(String.valueOf(period));
		fa.setArbeitsplatz(arbeitsplatz);
		fa.setErsteslos(String.valueOf(firstbatch));
		fa.setLetzteslos(String.valueOf(lastbatch));
		fa = fv.erstelleFertigungsauftrag(fa);
		fap.setFertigungsauftrag(fa);
		fap.setTeil(lv.findeTeilNachTeilId(Long.valueOf(item)));
		fap.setAuftragsmenge(amount);
		fap = fv.erstelleFertigungsauftragsposition(fap);
		fapl.add(fap);
		fa.setFertigungsauftragspositionen(fapl);
		fap = fv.aendereFertigungsauftragsposition(fap);
		fa = fv.aendereFertigungsauftrag(fa);
		warteschlangenAuftrage.add(fa);
		arbeitsplatz.setWarteschlangenAuftrage(warteschlangenAuftrage);
		try {
			lv.aendereArbeitsplatz(arbeitsplatz);
		} catch (ArbeitsplatzNotFoundException e) {
			throw new XMLException(
					"Error while updating a workstation in createWaitinglistworksatationsInserts()");
		}

	}

	/**
	 * Adds the current <waitinglistworkstations> element into the database (outer level)
	 * @param workplaceId
	 * @param workplaceTimeneed
	 * @throws XMLException  
	 */
	private void createWaitinglistworksatationsInserts(int workplaceId,
			int workplaceTimeneed) throws XMLException {
		if (TRACE)
			LOG.trace("DB insert: " + workplaceId + "; " + workplaceTimeneed);

		Arbeitsplatz arbeitsplatz;
		try {
			arbeitsplatz = lv
					.findeArbeitsplatzNachId(Long.valueOf(workplaceId));
		} catch (ArbeitsplatzNotFoundException e) {
			throw new XMLException("Arbeitsplatz: " + workplaceId
					+ " not found -> this shouldn't happen!");
		}

		arbeitsplatz.setZeitbedarfVorperiode(String.valueOf(workplaceTimeneed));
		try {
			lv.aendereArbeitsplatz(arbeitsplatz);
		} catch (ArbeitsplatzNotFoundException e) {
			throw new XMLException(
					"Error while updating a workstation in createIdletimecostsInserts() (outer level)");
		}

	}

	/**
	 * Adds the current <waitingliststock> element into the database
	 * @param id  missingpart
	 * @param period
	 * @param order
	 * @param firstbatch
	 * @param lastbatch
	 * @param item
	 * @param amount  
	 * @throws FehlendeteileNotFoundException  
	 * @throws TeilNotFoundException  
	 * @throws FertigungsauftragNotFoundException  
	 * @throws FertigungsauftragspositionDuplikatException  
	 */
	private void createWaitingliststockInserts(int id, int period, int order,
			int firstbatch, int lastbatch, int item, int amount)
			throws FehlendeteileNotFoundException, TeilNotFoundException,
			FertigungsauftragspositionDuplikatException,
			FertigungsauftragNotFoundException {
		if (TRACE)
			LOG.trace("DB insert: " + id + "; " + period + "; " + order + "; "
					+ firstbatch + "; " + lastbatch + "; " + item + "; "
					+ amount);

		List<Fertigungsauftragsposition> fapl = new ArrayList<Fertigungsauftragsposition>();
		Fertigungsauftrag fa = new Fertigungsauftrag();
		fa.setInterneAuftragsId(String.valueOf(order));
		fa.setBemerkung("WaitingListStock Missingpart " + id);
		fa = fv.erstelleFertigungsauftrag(fa);
		Fertigungsauftragsposition fap = new Fertigungsauftragsposition();
		fap.setTeil(lv.findeTeilNachTeilId(Long.valueOf(item)));
		fap.setFertigungsauftrag(fa);
		fap.setAuftragsmenge(amount);
		fap.setFertigungsauftrag(fa);
		fap = fv.erstelleFertigungsauftragsposition(fap);
		Fehlendeteile ft = new Fehlendeteile();
		ft.setFirstbatch(String.valueOf(firstbatch));
		ft.setLastbatch(String.valueOf(lastbatch));
		//ft.setAnzahl(String.valueOf(amount));
		ft.setMissingpart(String.valueOf(id));
		ft.setFertigungsauftragsposition(fap);
		fv.erstelleFehlendeteile(ft);
		fapl.add(fap);
		fa.setFertigungsauftragspositionen(fapl);
		fa = fv.aendereFertigungsauftrag(fa);
	}

	/**
	 * Adds the current <ordersinwork> element into the database 
	 * @param id
	 * @param period
	 * @param order
	 * @param batch
	 * @param item
	 * @param amount
	 * @param timeNeed
	 * @throws XMLException  
	 * @throws TeilNotFoundException  
	 * @throws FertigungsauftragNotFoundException  
	 * @throws FertigungsauftragspositionDuplikatException  
	 * @throws ArbeitsplatzNotFoundException  
	 */
	private void createOrdersinworkInserts(int id, int period, int order,
			int batch, int item, int amount, int timeNeed) throws XMLException,
			TeilNotFoundException, FertigungsauftragspositionDuplikatException,
			FertigungsauftragNotFoundException, ArbeitsplatzNotFoundException {
		if (TRACE)
			LOG.trace("DB insert: " + id + "; " + period + "; " + order + "; "
					+ batch + "; " + item + "; " + amount + "; " + timeNeed);

		Arbeitsplatz arbeitsplatz;
		try {
			arbeitsplatz = lv.findeArbeitsplatzNachId(Long.valueOf(id));
		} catch (ArbeitsplatzNotFoundException e) {
			throw new XMLException("Arbeitsplatz: " + id
					+ " not found -> this shouldn't happen!");
		}

		Fertigungsauftrag fa = new Fertigungsauftrag();
		fa.setTagdesauftrags(String.valueOf(period));
		fa.setInterneAuftragsId(String.valueOf(order));
		fa.setBemerkung("OrdersInWork AP" + id);
		fa.setZeitbedarf(String.valueOf(timeNeed));
		fv.erstelleFertigungsauftrag(fa);
		Fertigungsauftragsposition fap = new Fertigungsauftragsposition();
		fap.setTeil(lv.findeTeilNachTeilId(Long.valueOf(item)));
		fap.setFertigungsauftrag(fa);
		fap.setAuftragsmenge(amount);
		fap.setLos(String.valueOf(batch));
		fv.erstelleFertigungsauftragsposition(fap);
		List<Fertigungsauftragsposition> fapl = new ArrayList<Fertigungsauftragsposition>();
		fapl.add(fap);
		fa.setFertigungsauftragspositionen(fapl);
		fv.aendereFertigungsauftrag(fa);
		arbeitsplatz.setAktuellerauftrag(fa);
		lv.aendereArbeitsplatz(arbeitsplatz);
	}

	/**
	 * Adds the current <completedorders> element into the database (top level) 
	 * Not in use at the moment
	 * @param period
	 * @param id
	 * @param item
	 * @param quantity
	 * @param cost
	 * @param averageunitcosts
	 */
	private void createCompletedordersInserts(int period, int id, int item,
			int quantity, double cost, double averageunitcosts) {
		if (TRACE)
			LOG.trace("DB insert (tl): " + period + "; " + id + "; " + item
					+ "; " + quantity + "; " + cost + "; " + averageunitcosts);

		//Data not needed at this stage
	}

	/**
	 * Adds the current <completedorders> element into the database (lower level)
	 * Not in use at the moment
	 * @param llid
	 * @param amount
	 * @param cycletime
	 * @param llcost
	 */
	private void createCompletedordersInserts(int llid, int amount,
			int cycletime, double llcost) {
		if (TRACE)
			LOG.trace("DB insert (ll): " + llid + "; " + amount + "; "
					+ cycletime + "; " + llcost);

		//Data not needed at this stage
	}

	/**
	 * Adds the current <cycletimes> element into the database (top level)
	 * Not in use at the moment
	 * @param startedorders
	 * @param waitingorders
	 */
	private void createCycletimesInserts(int startedorders, int waitingorders) {
		if (TRACE)
			LOG.trace("DB insert (toplevel): " + startedorders + "; "
					+ waitingorders);

		//Data not needed at this stage
	}

	/**
	 * Adds the current <cycletimes> element into the database (lower level)
	 * Not in use at the moment
	 * @param period
	 * @param starttime
	 * @param finishtime
	 * @param cycletimemin
	 * @param cycletimefactor
	 */
	private void createCycletimesInserts(int period, String starttime,
			String finishtime, int cycletimemin, double cycletimefactor) {
		if (TRACE)
			LOG.trace("DB insert: " + period + "; " + starttime + "; "
					+ finishtime + "; " + cycletimemin + "; " + cycletimefactor);

		//Data not needed at this stage
	}

	/**
	 * Adds the current <result> element into the database
	 * Used to import the period and storagecosts information of the imported data
	 * @param period  current period n
	 * @param storagecosts  Storagecosts of period n-1
	 * @throws StaticDataNotFoundException  
	 * @throws NumberFormatException  
	 */
	private void createResultInserts(String period, String storagecosts)
			throws NumberFormatException, StaticDataNotFoundException {
		StaticData sdx = null;
		sdx = sdv.findStaticData(Long.valueOf("1"));
		Integer x = Integer.parseInt(period);
		x++;
		sdx.setPeriod(x.toString());
		sdx.setLagerkosten(storagecosts);
		sdx = sdv.changeStaticData(sdx);
	}

	/**
	 * toString()
	 * @return  String 
	 */
	@Override
	public String toString() {
		return "XMLImporter";
	}

	public IBestellverwaltung getBv() {
		return bv;
	}

	public void setBv(IBestellverwaltung bv) {
		this.bv = bv;
		System.out.println(bv);
	}

	public ILagerverwaltung getLv() {
		return lv;
	}

	public void setLv(ILagerverwaltung lv) {
		this.lv = lv;
		System.out.println(lv);
	}

	public IFertigungsverwaltung getFv() {
		return fv;
	}

	public void setFv(IFertigungsverwaltung fv) {
		this.fv = fv;
		System.out.println(fv);
	}

	public void setSdv(IStaticDataVerwaltung sdv) {
		this.sdv = sdv;
		System.out.println(sdv);
	}

	public IStaticDataVerwaltung getSdv() {
		return sdv;
	}

}
